package printer

import (
	"fmt"
)

// 颜色
//       前景色   背景色
// 黑色    30      40
// 红色    31      41
// 绿色    32      42
// 黄色    33      43
// 蓝色    34      44
// 紫色    35      45
// 青色    36      46
// 白色    37      47

// 文本模式
//  0    关闭所有颜色效果
//  1    高亮显示
//  4    使用下划线
//  5    闪烁
//  7    反白显示
//  8    不可见

const (
	FgBlack = iota + 30
	FgRed
	FgGreen
	FgYellow
	FgBlue
	FgPurple
	FgCyan
	FgWhite
)

const (
	BgBlack = iota + 40
	BgRed
	BgGreen
	BgYellow
	BgBlue
	BgPurple
	BgCyan
	BgWhite
)

const (
	MdDefault           = 0
	MdHighLight         = 1
	MdUnderline         = 4
	MdFlicker           = 5
	MdBackManifestation = 7
	MdInvisible         = 8
)

// 以Mode、BackGroundColor、FrontGroundColor模式打印。
type ColorMFB struct {
	//打印效果模式。
	//
	//Mode如果缺省，则无效果。
	Mode []int8
	//背景颜色。
	//
	//BgColor如果缺省，则无效果。
	BgColor int8
	//前景颜色。
	//
	//FgColor如果缺省，则无效果。
	FgColor int8
}

func (cm ColorMFB) Print(str string) {
	PrintByColorMFB(str, cm)
}

func (cm ColorMFB) Println(str string) {
	PrintlnByColorMFB(str, cm)
}

func (cm ColorMFB) SPrint(str string) string {
	return SprintByColorMFB(str, cm)
}

func (cm ColorMFB) Sprintln(str string) string {
	return SprintlnByColorMFB(str, cm)
}

func SprintByColorMFB(str string, color ColorMFB) string {
	var mo string
	if color.Mode != nil {
		for _, i := range color.Mode {
			mo = fmt.Sprint(mo, "\x1b[", i, "m")
		}
	}
	var fg, bg string
	if color.FgColor != 0 {
		fg = fmt.Sprintf("\x1b[%dm", color.FgColor)
	}
	if color.BgColor != 0 {
		bg = fmt.Sprintf("\x1b[%dm", color.BgColor)
	}
	return fmt.Sprintf("%s%s%s%s\x1b[0m", fg, bg, mo, str)
}

func SprintlnByColorMFB(str string, color ColorMFB) string {
	s := SprintByColorMFB(str, color)
	return s + "\n"
}

func PrintByColorMFB(str string, color ColorMFB) {
	s := SprintByColorMFB(str, color)
	fmt.Print(s)
	return
}

func PrintlnByColorMFB(str string, color ColorMFB) {
	s := SprintlnByColorMFB(str, color)
	fmt.Print(s)
}

type Color256 struct {
	//打印效果模式。
	//
	//Mode如果缺省，则无效果。
	Mode []int16
	//背景颜色。
	//
	//BgColor如果缺省，则无效果。
	BgColor int16
	//前景颜色。
	//
	//FgColor如果缺省，则无效果。
	FgColor int16
}

func (cm Color256) Print(str string) {
	PrintByColor256(str, cm)
}

func (cm Color256) Println(str string) {
	PrintlnByColor256(str, cm)
}

func (cm Color256) SPrint(str string) string {
	return SprintByColor256(str, cm)
}

func (cm Color256) Sprintln(str string) string {
	return SprintlnByColor256(str, cm)
}

func SprintByColor256(str string, color Color256) string {
	var mo string
	if color.Mode != nil {
		for _, i := range color.Mode {
			mo = fmt.Sprint(mo, "\x1b[", i, "m")
		}
	}
	var fg, bg string
	if color.FgColor != 0 {
		fg = fmt.Sprintf("\x1b[38;5;%dm", color.FgColor)
	}
	if color.BgColor != 0 {
		bg = fmt.Sprintf("\x1b[48;5;%dm", color.BgColor)
	}
	return fmt.Sprintf("%s%s%s%s\x1b[0m", fg, bg, mo, str)
}

func SprintlnByColor256(str string, color Color256) string {
	s := SprintByColor256(str, color)
	return s + "\n"
}

func PrintByColor256(str string, color Color256) {
	s := SprintByColor256(str, color)
	fmt.Print(s)
}

func PrintlnByColor256(str string, color Color256) {
	s := SprintlnByColor256(str, color)
	fmt.Print(s)
}
